﻿/// <summary>
/// FileName: ICustomFunction.cs
/// Author: Jiang Xiaolong
/// Created Time: 2015.05.12
/// Version: 1.0
/// Company: Sunnytech
/// Function: 字符缓存基类，用于单个char和一个分词Token；
///
/// Changed By:
/// Modification Time:
/// Discription:
/// </summary>

using System.Collections.Generic;
using Expression.impl;

namespace Expression.api
{
	public abstract class ForwardQuery<T>
	{
		//当前缓存；
		protected List<T> ItemBuffer = new List<T>();

		//是否到行尾；
		protected bool EndReached = false;

		//错误列表；
		protected List<ParseError> problemCollector = new List<ParseError>();

		//行尾标志；
		protected T endOfInputIndicator;

		/// <summary>
		/// 当前项，不会改变当前项位置；
		/// </summary>
		/// <returns>返回当前项；</returns>
		public T current()
		{
			return next(0);
		}

		/// <summary>
		/// 下一项，不会改变当前项位置；
		/// </summary>
		/// <returns>返回下一项；</returns>
		public T next()
		{
			return next(1);
		}

		/// <summary>
		/// 下面n项，不会改变当前项位置；
		/// </summary>
		/// <param name="offset">偏移位置；</param>
		/// <returns>返回第n项；</returns>
		public T next(int offset)
		{
			if (offset < 0)
			{
				return default(T);
			}
			while (ItemBuffer.Count <= offset && !EndReached)
			{
				T item = Fetch();
				if (item != null)
				{
					ItemBuffer.Add(item);
				}
				else
				{
					EndReached = true;
				}
			}
			if (offset >= ItemBuffer.Count)
			{
				if (endOfInputIndicator == null)
				{
					endOfInputIndicator = EndOfInput();
				}
				return endOfInputIndicator;
			}
			else
			{
				return ItemBuffer[offset];
			}
		}

		/// <summary>
		/// 结尾项；
		/// </summary>
		/// <returns>结尾项；</returns>
		protected abstract T EndOfInput();

		/// <summary>
		/// 获取项；
		/// </summary>
		/// <returns>获取项；</returns>
		protected abstract T Fetch();

		/// <summary>
		/// 移动到下一个位置；
		/// </summary>
		/// <returns>下一位置；</returns>
		public T consume()
		{
			T result = current();
			consume(1);
			return result;
		}

		/// <summary>
		/// 移动到下n个位置；
		/// </summary>
		/// <param name="numberOfItems"></param>
		public void consume(int numberOfItems)
		{
			if (numberOfItems < 0)
			{
				return ;
			}
			while (numberOfItems-- > 0)
			{
				if (ItemBuffer.Count != 0)
				{
					ItemBuffer.RemoveAt(0);
				}
				else
				{
					if (EndReached)
					{
						return;
					}
					else
					{
						T item = Fetch();
						if (item == null)
						{
							EndReached = true;
						}
					}
				}
			}
		}

		/// <summary>
		/// 错误问题列表；
		/// </summary>
		/// <returns></returns>
		public List<ParseError> GetProblemCollector()
		{
			return problemCollector;
		}

		/// <summary>
		/// 设置问题列表索引；
		/// </summary>
		/// <param name="problemCollector"></param>
		public virtual void SetProblemCollector(List<ParseError> problemCollector)
		{
			this.problemCollector = problemCollector;
		}
	}

}